/*
 * Copyright (c) 2021 柯华栋
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IPC_CLIENT_H
#define IPC_CLIENT_H

#include "ipc_util.h"

typedef void (*ipc_on_update)(gpointer* ud, ipc_map_t* map);

typedef struct 
{
	ipc_on_update on_update;
	gpointer* ud;
} ipc_observer_t;

// (代码最开始的位置先调用ipc_init(), 再调用client_init())
void client_init(const gchar* client_name);

/** 再进行ipc调用前先设定模块的服务名(如果不设置，服务名就是模块名), 用于共享连接，减少连接数 */
void client_set_module_server_name(const gchar* module_name, const gchar* server_name);

/** 通过配置文件设置模块的服务名 */
void client_set_module_server_name_by_config_file(void);

/** 获取在监听中的id */
ipc_string_array_t* client_get_observing_ids();

typedef struct _ipc_observer_array_t ipc_observer_array_t;

/** 获取指定id的监听器 */
ipc_observer_array_t* client_get_ipc_observer_array(const gchar* id);

/** 添加和删除引用 */
int ipc_observer_array_ref(ipc_observer_array_t* array);
int ipc_observer_array_unref(ipc_observer_array_t* array);
int ipc_observer_array_size(ipc_observer_array_t* array);
ipc_observer_t* ipc_observer_array_get(ipc_observer_array_t* array, int pos);



// 基本IPC函数 -------------------------------------------------------------------
// TODO. 如果服务没运行起来， IPC会失败，需要使用某中机制确保服务运行起来了

// (注意!!! 内部会进行ipc_map_unref)
void 		client_post(ipc_map_t* map);

// (注意!!! 内部会进行ipc_map_unref)
ipc_map_t* 	client_send(ipc_map_t* map);

void client_add_observer	(const gchar* id, ipc_observer_t* observer);
void client_remove_observer (const gchar* id, ipc_observer_t* observer);

// post衍生函数(只附加一个_value参数)
void client_post_u8(const gchar* id, uint8_t value);
void client_post_s16(const gchar* id, int16_t value);
void client_post_s32(const gchar* id, int32_t value);
void client_post_s64(const gchar* id, int64_t value);
void client_post_float(const gchar* id, float value);
void client_post_double(const gchar* id, double value);
void client_post_string(const gchar* id, const gchar* value);

void client_post_u8_array(const gchar* id, ipc_u8_array_t* array);
void client_post_s16_array(const gchar* id, ipc_s16_array_t* array);
void client_post_s32_array(const gchar* id, ipc_s32_array_t* array);
void client_post_s64_array(const gchar* id, ipc_s64_array_t* array);
void client_post_float_array(const gchar* id, ipc_float_array_t* array);
void client_post_double_array(const gchar* id, ipc_double_array_t* array);
void client_post_string_array(const gchar* id, ipc_string_array_t* array);

// send衍生函数(只附加一个“_value”参数)
// 如果返回值只有一个参数可以使用ipc_map_get_xxx(map, KEY_VALUE)来获取
ipc_map_t* client_send_u8(const gchar* id, uint8_t value);
ipc_map_t* client_send_s16(const gchar* id, int16_t value);
ipc_map_t* client_send_s32(const gchar* id, int32_t value);
ipc_map_t* client_send_s64(const gchar* id, int64_t value);
ipc_map_t* client_send_float(const gchar* id, float value);
ipc_map_t* client_send_double(const gchar* id, double value);
ipc_map_t* client_send_string(const gchar* id, const gchar* value);


ipc_map_t* client_send_u8_array(const gchar* id, ipc_u8_array_t* array);
ipc_map_t* client_send_s16_array(const gchar* id, ipc_s16_array_t* array);
ipc_map_t* client_send_s32_array(const gchar* id, ipc_s32_array_t* array);
ipc_map_t* client_send_s64_array(const gchar* id, ipc_s64_array_t* array);
ipc_map_t* client_send_float_array(const gchar* id, ipc_float_array_t* array);
ipc_map_t* client_send_double_array(const gchar* id, ipc_double_array_t* array);
ipc_map_t* client_send_string_array(const gchar* id, ipc_string_array_t* array);



#endif	// IPC_CLIENT_H

